//
//  HACStockKLine.m
//  Pods
//
//  Created by Hotacool on 2017/9/5.
//
//

#import "HACStockKLine.h"
#import "HACKLineView.h"
#import "HACTecView.h"
#import "HACKLineEntry.h"

static const CGFloat refreshViewWidth = 30;
@interface HACStockKLine ()
@property (nonatomic, strong) HACKLineView *klineView;
@property (nonatomic, strong) HACTecView *tecView;

@end

@implementation HACStockKLine {
    CGPoint _preOffset;
    NSInteger _lastTotalCount;
    CGFloat _originSingleWidth;//初始单根线宽度
}

- (void)setUp {
    [super setUp];
    //设置为可滑动加载历史K线
    self.contentView.bounces = YES;
    // 缩放控制
    self.minScale = 0.3;
    self.maxScale = 3;
    self.lastEndScale = 1.0;
    self.effectScale = 0.1;
    
    //分时图
    _klineView = [[HACKLineView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height*.6)];
    [self.contentView addSubview:_klineView];
    //指标 量
    _tecView = [[HACTecView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(_klineView.frame)+10, self.frame.size.width, self.frame.size.height-_klineView.frame.size.height-30)];
    [_tecView setViewType:HACTecViewTypeKLine andIndexType:HACTecViewIndexTypeVol];
    [self.contentView addSubview:_tecView];
    
//    _tecView.leftAxis = self.klineView.leftAxis;
//    _tecView.rightAxis = self.klineView.rightAxis;
}

- (HACAxisComponents *)leftAxis {
    return _klineView.leftAxis;
}

- (HACAxisComponents *)rightAxis {
    return _klineView.rightAxis;
}

- (void)setFrame:(CGRect)frame {
    [super setFrame:frame];
    _klineView.frame = CGRectMake(0, 0, frame.size.width, frame.size.height*.6);
    _tecView.frame = CGRectMake(0, CGRectGetMaxY(_klineView.frame)+10, frame.size.width, frame.size.height-_klineView.frame.size.height-30);
    //content size
    CGFloat maxWidth = MAX(self.klineView.actualCount, self.tecView.actualCount)*MAX(self.klineView.singleWidth, self.tecView.singleWidth);
    self.contentView.contentSize = CGSizeMake(maxWidth, self.contentView.frame.size.height);
    [self updateSubViewsFrameWithOffset:self.contentView.contentOffset];
    
    self.refreshIndicator.center = CGPointMake(self.refreshIndicator.center.x, _klineView.frame.size.height/2);
}

- (void)refreshWithData:(HACChartData *)data {
    self.data = data;
    [self.klineView setData:data];
    [self.tecView setData:data];
    
    [self updatePosition];
    _lastTotalCount = self.klineView.actualCount;
}

- (void)endRefreshWithData:(HACChartData *)data {
    NSLog(@"***scrollView.contentOffset: %s,  %f", __func__, self.contentView.contentOffset);
    self.data = data;
    [self.klineView setData:data];
    [self.tecView setData:data];
    
    [self updatePosition];
    //setContentInset触发didscroll, 需先updatePosition，后复写refresh indicator
    [self.refreshIndicator stopAnimating];
    CGPoint offset = self.contentView.contentOffset;
    [self.contentView setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)];
    if (_lastTotalCount < self.klineView.actualCount) {//load more 情况下offset保持； 没有更多时归零
        [self.contentView setContentOffset:offset animated:NO];
    }
    _lastTotalCount = self.klineView.actualCount;
    self.isRefresh = NO;
}

- (void)refreshUI {
    [self.klineView refreshUI];
    [self.tecView refreshUI];
}

- (void)resetToLatest {
    self.indexFromEnd = 0;
    [self updatePosition];
}

- (void)reset {
    [super reset];
    [self.klineView clean];
    [self.tecView clean];
    [self resetToLatest];
}

- (void)setVisualCount:(NSInteger)visualCount {
    [self.klineView setVisualCount:visualCount];
    [self.tecView setVisualCount:visualCount];
}
#pragma mark - actions
- (void)reactForLongPressGesture:(UILongPressGestureRecognizer *)gesture {
    CGPoint point = [gesture locationInView:self];
    if (gesture.state == UIGestureRecognizerStateBegan || gesture.state == UIGestureRecognizerStateChanged) {
        //偏移，因gesture所在view不随scroll移动
        point = CGPointMake(point.x + self.contentView.contentOffset.x, point.y + self.contentView.contentOffset.y);
        self.focusIndex = [self.klineView indexAtChartForCoordinate:point];;
        self.focusPoint = [self.klineView pointAtChartForIndex:self.focusIndex];
    } else {
        self.focusIndex = -1;
    }
}

- (void)reactForContentViewDidScroll:(UIScrollView *)scrollView {
    CGPoint offset = scrollView.contentOffset;
    NSLog(@"***scrollView.contentOffset: %s,  %f", __func__, self.contentView.contentOffset);
    // update data
    CGFloat d = offset.x - _preOffset.x;
    if (ABS(d) > self.klineView.singleWidth) {
        int ts, te;
        [self calculateStartIdx:&ts endIdx:&te byOffset:offset];
        
        self.indexFromEnd = floor((scrollView.contentSize.width-(offset.x+self.klineView.frame.size.width))/self.klineView.singleWidth);
        [self updateSubViewsStartIdx:ts endIdx:te];
        
        [self refreshUI];
        _preOffset = offset;
    }
    [self updateSubViewsFrameWithOffset:offset];
}

- (void)reactForPinchGesture:(UIPinchGestureRecognizer *)gesture {
    if (_originSingleWidth==0) {
        _originSingleWidth = self.klineView.singleWidth;
    }
    CGFloat scale = gesture.scale;
    if (gesture.state ==UIGestureRecognizerStateBegan) {
        self.contentView.scrollEnabled = NO;
    } else if (gesture.state ==UIGestureRecognizerStateChanged) {
        //在手势的changed过程中，每一个changed时候获取的scale值都是和begin时的值的比率
        if (ABS(scale - self.lastScale) >= self.effectScale) {
            // 变化量大于生效阀值才调整
            CGFloat currentScale = self.lastEndScale * scale; // 当前次缩放与本次缩放最原始的比例
            if (currentScale >= self.minScale && currentScale <= self.maxScale) {
                // 调整singleWidth和visualCount
                CGFloat visualWidth = CGRectGetWidth(self.klineView.frame);
                CGFloat nsw= _originSingleWidth * currentScale;
                int nvc = ceil(visualWidth / nsw);
                self.klineView.visualCount = nvc;
                self.tecView.visualCount = nvc;
                //从右往左延伸
                [self updatePosition];
            }
            self.lastScale = scale;
        }
    } else if ((gesture.state == UIGestureRecognizerStateEnded) // 结束
             || (gesture.state == UIGestureRecognizerStateCancelled)
             || (gesture.state == UIGestureRecognizerStateFailed))
         {
        // 当手指离开屏幕时,将lastEndScale设置会最后的scale,用于下次使用
        CGFloat currentScale = self.lastEndScale * scale; // 本次缩放与最原始的比例
        self.lastEndScale = MIN(MAX(self.minScale, currentScale), self.maxScale);
        self.contentView.scrollEnabled = YES;
    }
}

#pragma mark - provider
- (NSArray *)focusDataInRect:(CGRect)rect focusIndex:(NSInteger)focusIndex {
    if (self.focusItemsCount == 0 || focusIndex >= self.klineView.actualCount || focusIndex == -1)
        return nil;
    
    NSMutableArray *focusDrawingData = [NSMutableArray array];
    CGFloat x = 0.0, y = 0.0;
    for (NSInteger i = 0; i < self.focusItemsCount; i++) {
        HACFocusComponents *item = [[HACFocusComponents alloc] init];
        item.index = i;
        item.axisType = i == 0 ? DrawingAxisTypeY : DrawingAxisTypeX; //第一根是竖线，第二根横线
        item.text = [self stringForFocusItem:item focusIndex:focusIndex];
        
        CGSize textSize = [item.text sizeWithAttributes:@{NSFontAttributeName : item.textFont}];
        CGRect frame = CGRectMake(CGRectGetMinX(rect), CGRectGetMinY(rect), textSize.width , textSize.height);
        CGLine line = CGLineMake(0, 0, 0, 0);
        
        CGPoint focusPoint = [self.klineView pointAtChartForIndex:focusIndex];
        focusPoint = CGPointMake(focusPoint.x, focusPoint.y);
        
        if (item.axisType == DrawingAxisTypeX) {
            y = focusPoint.y;
            line = CGLineMake(CGRectGetMinX(rect) + textSize.width, y, CGRectGetMaxX(rect), y);
            frame.origin.y = MIN(CGRectGetMaxY(rect), MAX(CGRectGetMinY(rect), y - textSize.height / 2));
        } else {
            x = focusPoint.x;
            line = CGLineMake(x, CGRectGetMinY(rect), x, CGRectGetMaxY(rect));
            frame.origin.x = MIN(CGRectGetMaxX(rect) - textSize.width, MAX(CGRectGetMinX(rect), x - textSize.width / 2));
            frame.origin.y = CGRectGetMaxY(rect);
        }
        
        item.textFrame = frame;
        item.line = line;
        item.point = focusPoint;
        [focusDrawingData addObject:item];
    }
    return focusDrawingData;
}

- (NSString *)stringForFocusItem:(HACFocusComponents *)focusItem focusIndex:(NSInteger)focusIndex {
    NSString *focusString;
    NSInteger idx = focusIndex + self.klineView.startIndex;
    HACKLineEntry *data = (HACKLineEntry *)[self.klineView dataAtChartForIndex:idx];
    if (focusItem.axisType == DrawingAxisTypeX) {
        focusString = @(data.closePrice).stringValue;
    }
    return focusString;
}

- (void)calculateStartIdx:(int*)ts endIdx:(int*)te byOffset:(CGPoint)offset {
    int m = offset.x/self.klineView.singleWidth;
    *ts = m>=0?m:0;
    *te = (m+self.klineView.visualCount)<=self.klineView.actualCount?(m+self.klineView.actualCount):self.klineView.visualCount;
    if (m<=0) {
        //滑到最左边，左边已无更多历史数据，模拟scroll bounce左边显示空白
        *ts = 0;
        *te = m+self.klineView.visualCount-1;
    } else {
        if (m>self.klineView.actualCount-self.klineView.visualCount) {
            //滑到最右边，右边已无更多最新数据，模拟scroll bounce右边显示空白
            *ts = m;
            *te = self.klineView.actualCount-1;
        } else {
            *ts = m;
            *te = m+self.klineView.visualCount-1;
        }
    }
}

- (void)updatePosition {
    [self updateContentViewOffset];
    CGPoint offset = self.contentView.contentOffset;
    int ts, te;
    [self calculateStartIdx:&ts endIdx:&te byOffset:offset];
    [self updateSubViewsStartIdx:ts endIdx:te];
    [self refreshUI];
    [self updateSubViewsFrameWithOffset:self.contentView.contentOffset];
}

- (void)updateContentViewOffset {
    CGSize oldContentSize = self.contentView.contentSize;
    if (self.klineView.actualCount<=self.klineView.visualCount) {//数据未达到显示根数
        self.indexFromEnd = 0;
        CGFloat maxWidth = self.klineView.frame.size.width;
        self.contentView.contentSize = CGSizeMake(maxWidth, self.contentView.frame.size.height);
        self.contentView.contentOffset = CGPointMake(maxWidth-self.klineView.frame.size.width, 0);
    } else {
        //klineView 实际大小
        CGFloat maxWidth = self.klineView.actualCount*self.klineView.singleWidth+(self.klineView.frame.size.width-self.klineView.pointRect.size.width);
        if (_lastTotalCount>self.klineView.actualCount) {
            //不应存在这种情况：K线数据减少
            self.indexFromEnd = 0;
            self.contentView.contentOffset = CGPointMake(maxWidth-self.klineView.frame.size.width, 0);
        } else {
            if (oldContentSize.width>maxWidth) {//缩小
                if (self.contentView.contentOffset.x <= 0) {//保持最前
                    self.contentView.contentOffset = CGPointMake(0, 0);
                }
            } else {
                //K线数据增加/拉伸，scroll保持上次位置
                self.contentView.contentOffset = CGPointMake(maxWidth-self.klineView.frame.size.width-self.indexFromEnd*self.klineView.singleWidth, 0);
                NSLog(@"***scrollView.contentOffset: %s,  %f", __func__, self.contentView.contentOffset);
            }
        }
        //set contentsize 触发didscroll, 延后赋值
        self.contentView.contentSize = CGSizeMake(maxWidth, self.contentView.frame.size.height);
    }
}

- (void)updateSubViewsFrameWithOffset:(CGPoint)offset {
    self.klineView.frame = CGRectMake(offset.x, self.klineView.frame.origin.y, self.klineView.frame.size.width, self.klineView.frame.size.height);
    self.tecView.frame = CGRectMake(offset.x, self.tecView.frame.origin.y, self.tecView.frame.size.width, self.tecView.frame.size.height);
}

- (void)updateSubViewsStartIdx:(NSInteger)start endIdx:(NSInteger)end {
    self.klineView.startIndex = start;
    self.klineView.endIndex = end;
    self.tecView.startIndex = start;
    self.tecView.endIndex = end;
}
@end
